package geometry3D;

import context.*;

import util.Transform;

import java.awt.Color;

import javax.media.j3d.Alpha;
import javax.media.j3d.AmbientLight;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Group;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
import com.sun.j3d.utils.behaviors.mouse.MouseWheelZoom;
import com.sun.j3d.utils.behaviors.mouse.MouseZoom;

public class SceneGraph implements Context.Constants
{ //private static final boolean DEBUG=true; // Overriding Context.Constants.DEBUG

  
  // *************************************************************************
  // *** METHOD: createSceneGraph
  // *************************************************************************
  public BranchGroup createSceneGraph(Group model)
  {  // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();

    // Create a Transformgroup to scale all objects so they appear in the scene.
    TransformGroup objScale=new TransformGroup();
    Transform3D t3d=new Transform3D();
//    t3d.setScale(0.1);
    t3d.setScale(0.05);
    objScale.setTransform(t3d);
    objRoot.addChild(objScale);

    // Create the transform group node and initialize it to the
    // identity.  Enable the TRANSFORM_WRITE capability so that
    // our behavior code can modify it at runtime.  Add it to the
    // root of the subgraph.
    TransformGroup objTrans=new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    objScale.addChild(objTrans);
    
    // Set initial view transformation
    Transform3D t=new Transform3D();
//  t=Transform.move(t,-1.0,0,0);
    t=Transform.rotate(t,Math.PI/16,Math.PI/4,Math.PI/16);
    objTrans.setTransform(t);

    objTrans.addChild(model); // HER LEGGES MODELLEN INN !!!!!!!
    
    if(ADD_COORDINATE_SYSTEM)
    { CoordSys coordSys = new CoordSys(50);//(coordSysLength);    // the coordSys
      objTrans.addChild(coordSys);            
    }
//    BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
    BoundingSphere bounds=new BoundingSphere(new Point3d(10.0,10.0,0.0), 30.0);
    if(SPIN_MODEL)
    { Transform3D yAxis=new Transform3D();
    
      yAxis=Transform.rotate(yAxis,Math.PI/16,Math.PI/4,Math.PI/16);
    
//      Alpha rotationAlpha=new Alpha(-1,Alpha.INCREASING_ENABLE,0,0,4000,0,0,0,0,0);
      Alpha rotationAlpha=new Alpha(-1,Alpha.INCREASING_ENABLE,0,0,32000,0,0,0,0,0);
      RotationInterpolator rotator=new RotationInterpolator(rotationAlpha,objTrans,yAxis,0.0f,(float)Math.PI*2.0f);
      rotator.setSchedulingBounds(bounds);
      objTrans.addChild(rotator);
    }
    else
    { // Create the rotate behavior node
      MouseRotate behavior=new MouseRotate();
      behavior.setTransformGroup(objTrans);
      objTrans.addChild(behavior);
      behavior.setSchedulingBounds(bounds);

      // Create the zoom behavior node
      MouseZoom behavior2=new MouseZoom();
      behavior2.setTransformGroup(objTrans);
      objTrans.addChild(behavior2);
      behavior2.setSchedulingBounds(bounds);

      // Create the translate behavior node
      MouseTranslate behavior3=new MouseTranslate();
      behavior3.setTransformGroup(objTrans);
      objTrans.addChild(behavior3);
      behavior3.setSchedulingBounds(bounds);

      // Create the wheel zoom behavior node
      MouseWheelZoom behavior4=new MouseWheelZoom();
      behavior4.setTransformGroup(objTrans);
      objTrans.addChild(behavior4);
      behavior4.setSchedulingBounds(bounds);
    }

    // Set up the background
//    Color3f bgColor=new Color3f(0.05f,0.05f,0.5f);
    Color3f bgColor=new Color3f(Color.white);
    Background bgNode=new Background(bgColor);
    bgNode.setApplicationBounds(bounds);
    objRoot.addChild(bgNode);

    // Set up the ambient light
    Color3f ambientColor=new Color3f(0.1f,0.1f,0.1f);
    AmbientLight ambientLightNode=new AmbientLight(ambientColor);
    ambientLightNode.setInfluencingBounds(bounds);
    objRoot.addChild(ambientLightNode);

    // Set up the directional lights
    Color3f light1Color=new Color3f(1.0f,1.0f,0.9f);
    Vector3f light1Direction=new Vector3f(4.0f,-7.0f,-12.0f);
    DirectionalLight light1=new DirectionalLight(light1Color,light1Direction);
    light1.setInfluencingBounds(bounds);
    objRoot.addChild(light1);

    Color3f light2Color=new Color3f(0.3f,0.3f,0.4f);
    Vector3f light2Direction=new Vector3f(-6.0f,-2.0f,-1.0f);
    DirectionalLight light2=new DirectionalLight(light2Color,light2Direction);
    light2.setInfluencingBounds(bounds);
    objRoot.addChild(light2);

    return objRoot;
  }

}
